package com.peas.platform.module.icims.expenditure.kpis.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.peas.platform.common.core.dto.ResponseDto;
import com.peas.platform.common.core.utils.ExcelTool;
import com.peas.platform.framework.mybatisplus.utils.PageUtil;
import com.peas.platform.module.icims.expenditure.kpis.controller.criteria.ExpenditureKpiItemCriteria;
import com.peas.platform.module.icims.expenditure.kpis.controller.vo.ExpenditureKpiItemVo;
import com.peas.platform.module.icims.expenditure.kpis.dto.ExpenditureKpiItemDto;
import com.peas.platform.module.icims.expenditure.kpis.service.ExpenditureKpiItemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.SneakyThrows;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Api(tags = "【指标单经济支出预算】接口")
@RestController
@RequestMapping("/api/v1/expenditure-kpi-item")
public class ExpenditureKpiItemController {

    @Resource
    private HttpServletRequest request;
    @Resource
    private HttpServletResponse response;
    @Resource
    private ExpenditureKpiItemService expenditureKpiItemService;

    @ApiOperation(value = "添加指标单经济支出预算")
    @PostMapping("/add")
    public ResponseDto<Integer> add(@RequestBody @Valid ExpenditureKpiItemVo expenditureKpiItemVo) {
        ExpenditureKpiItemDto dto = BeanUtil.copyProperties(expenditureKpiItemVo, ExpenditureKpiItemDto.class);
        int result = expenditureKpiItemService.save(dto);
        return ResponseDto.getSuccessResponseDto(result);
    }

    @ApiOperation(value = "删除指标单经济支出预算")
    @DeleteMapping("/{id}")
    public ResponseDto<Integer> delete(@ApiParam(name = "id", value = "要删除的数据主键ID", example = "1") @PathVariable("id") Long id) {
        int result = expenditureKpiItemService.removeById(id);
        return ResponseDto.getSuccessResponseDto(result);
    }

    @ApiOperation(value = "修改指标单经济支出预算")
    @PutMapping("/modify")
    public ResponseDto<Integer> modify(@RequestBody @Valid ExpenditureKpiItemVo expenditureKpiItemVo) {
        ExpenditureKpiItemDto dto = BeanUtil.copyProperties(expenditureKpiItemVo, ExpenditureKpiItemDto.class);
        int result = expenditureKpiItemService.updateById(dto);
        return ResponseDto.getSuccessResponseDto(result);
    }

    @ApiOperation(value = "根据ID查询指标单经济支出预算")
    @GetMapping("/{id}")
    public ResponseDto<ExpenditureKpiItemVo> id(@ApiParam(name = "id", value = "查询的主键ID", example = "1") @PathVariable("id") Long id) {
        ExpenditureKpiItemDto dto = expenditureKpiItemService.getById(id);
        ExpenditureKpiItemVo vo = BeanUtil.copyProperties(dto, ExpenditureKpiItemVo.class);
        return ResponseDto.getSuccessResponseDto(vo);
    }

    @ApiOperation(value = "根据多个ID查询指标单经济支出预算")
    @GetMapping("/ids")
    public ResponseDto<List<ExpenditureKpiItemVo>> ids(@ApiParam(name = "ids", value = "查询多个主键的id，用半角逗号分隔", example = "1,2,3,4,5") String ids) {
        List<Long> list = new ArrayList<>();
        CollUtil.forEach(StrUtil.split(ids, ','), (CollUtil.Consumer<String>) (id, index) -> list.add(Long.parseLong(id)));
        List<ExpenditureKpiItemDto> result = expenditureKpiItemService.listByIds(list);
        List<ExpenditureKpiItemVo> r = BeanUtil.copyToList(result, ExpenditureKpiItemVo.class);
        return ResponseDto.getSuccessResponseDto(r);
    }

    @ApiOperation(value = "根据某个字段查询指标单经济支出预算")
    @GetMapping("/listByField")
    public ResponseDto<List<ExpenditureKpiItemVo>> listByField(@ApiParam(name = "field", value = "要查询的字段", example = "id") String field,
                                                    @ApiParam(name = "values", value = "字段对应的多个值，用半角逗号分隔", example = "1,2,3,4,5") String values) {
        List<String> list = StrUtil.split(values, StrUtil.COMMA);
        List<ExpenditureKpiItemDto> result = expenditureKpiItemService.listByField(field, list);
        List<ExpenditureKpiItemVo> r = BeanUtil.copyToList(result, ExpenditureKpiItemVo.class);
        return ResponseDto.getSuccessResponseDto(r);
    }

    @ApiOperation(value = "根据条件查询指标单经济支出预算（分页）")
    @GetMapping("/page")
    public ResponseDto<Page<ExpenditureKpiItemVo>> page(ExpenditureKpiItemCriteria condition,
                                 @ApiParam(name = "pageNum", value = "分页页码", example = "1") Integer pageNum,
                                 @ApiParam(name = "pageSize", value = "分页每页大小", example = "10") Integer pageSize,
                                 @ApiParam(name = "sortField", value = "排序字段", example = "id") String sortField,
                                 @ApiParam(name = "sortType", value = "排序方式", example = "desc") String sortType) {
        Page<ExpenditureKpiItemDto> pager = PageUtil.genPager(pageNum, pageSize, sortField, sortType);
        ExpenditureKpiItemDto c = BeanUtil.copyProperties(condition, ExpenditureKpiItemDto.class);
        Page<ExpenditureKpiItemDto> page = expenditureKpiItemService.page(pager, c);
        Page<ExpenditureKpiItemVo> vos = PageUtil.copyPage(page, ExpenditureKpiItemVo.class);
        return ResponseDto.getSuccessResponseDto(vos);
    }

    @ApiOperation(value = "根据条件搜索指标单经济支出预算（分页）")
    @GetMapping("/search")
    public ResponseDto<Page<ExpenditureKpiItemVo>> search(ExpenditureKpiItemCriteria condition,
                                 @ApiParam(name = "pageNum", value = "分页页码", example = "1") Integer pageNum,
                                 @ApiParam(name = "pageSize", value = "分页每页大小", example = "10") Integer pageSize,
                                 @ApiParam(name = "sortField", value = "排序字段", example = "id") String sortField,
                                 @ApiParam(name = "sortType", value = "排序方式", example = "desc") String sortType) {
        Page<ExpenditureKpiItemDto> pager = PageUtil.genPager(pageNum, pageSize, sortField, sortType);
        Map<String, Object> c = BeanUtil.beanToMap(condition);
        Page<ExpenditureKpiItemDto> page = expenditureKpiItemService.page(pager, c);
        Page<ExpenditureKpiItemVo> vos = PageUtil.copyPage(page, ExpenditureKpiItemVo.class);
        return ResponseDto.getSuccessResponseDto(vos);
    }

    @SneakyThrows
    @ApiOperation(value = "根据条件导出指标单经济支出预算")
    @GetMapping("/export")
    public void export(ExpenditureKpiItemCriteria condition) {
        try {
            assert request != null;
            ExpenditureKpiItemDto c = BeanUtil.copyProperties(condition, ExpenditureKpiItemDto.class);
            List<ExpenditureKpiItemDto> page = expenditureKpiItemService.list(c);
            String file = "导出指标单经济支出预算-" + DateUtil.today() + ".xlsx";
            String name = URLEncoder.encode(file, StandardCharsets.UTF_8.name());
            List<String> head = new ArrayList<>();
            head.add("ID");
            for (Field f : ExpenditureKpiItemVo.class.getDeclaredFields()) {
                f.setAccessible(true);
                ApiModelProperty amp = f.getAnnotation(ApiModelProperty.class);
                if (amp != null) {
                    head.add(amp.value());
                }
            }
            head.add("创建时间");
            head.add("最后修改时间");
            List<List<?>> data = new ArrayList<>();
            if (CollUtil.isNotEmpty(page)) {
                for (ExpenditureKpiItemDto dto : page) {
                    ExpenditureKpiItemVo vo = BeanUtil.copyProperties(dto, ExpenditureKpiItemVo.class);
                    List<Serializable> row = new ArrayList<>();
                    row.add(String.valueOf(dto.getId()));
                    for (Field f : ExpenditureKpiItemVo.class.getDeclaredFields()) {
                        f.setAccessible(true);
                        ApiModelProperty amp = f.getAnnotation(ApiModelProperty.class);
                        if (amp != null) {
                            String v = ExcelTool.convertValue(f.get(vo), amp);
                            row.add(v);
                        }
                    }
                    row.add(DateUtil.formatDateTime(dto.getCreateTime()));
                    row.add(DateUtil.formatDateTime(dto.getUpdateTime()));
                    data.add(row);
                }
            }
            try (ExcelWriter writer = ExcelTool.genExcelWriter(head, data)) {
                response.setHeader("Content-disposition", "attachment; filename=" + name);
                response.setCharacterEncoding(StandardCharsets.UTF_8.name());
                response.setContentType("application/vnd.ms-excel;charset=utf-8");
                writer.flush(response.getOutputStream(), true);
            }
        } catch (Exception e) {
            response.setContentType(new MediaType(MediaType.APPLICATION_JSON, StandardCharsets.UTF_8).toString());
            throw e;
        }
    }

}
